package com.ocom.webapi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.constant.AccessServiceUrl;
import com.ocom.common.dto.AccountPageBaseDto;
import com.ocom.common.dto.CompanyDockListDto;
import com.ocom.common.dto.GetCompanyRoleListDto;
import com.ocom.common.dto.RefreshUserDockDto;
import com.ocom.common.entity.access.EntityMjAreaInfo;
import com.ocom.common.entity.access.EntityMjRegionInfo;
import com.ocom.common.entity.human.EntityDeptInfo;
import com.ocom.common.entity.master.EntityMngUserInfo;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.resp.RespMachMessage;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.PasswordValidator;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.company.ComDockApiListVo;
import com.ocom.common.vo.company.CompanyDockListVo;
import com.ocom.common.vo.company.CompanyRoleListVo;
import com.ocom.security.authentication.YoCiUser;
import com.ocom.security.utils.SecurityUtils;
import com.ocom.webapi.feign.AccessClientService;
import com.ocom.webapi.feign.CompanyClientService;
import com.ocom.webapi.feign.HumanClientService;
import com.ocom.webapi.feign.SrvpaccessClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@PreAuthorize("@pms.hasRole('ROLE_WEB')" )
public class AccountPageController {

    @Autowired
    private HumanClientService humanClientService;

    @Autowired
    private AccessClientService accessClientService;

    @Autowired
    private SrvpaccessClientService srvpaccessClientService;

    @Autowired
    private CompanyClientService companyClientService;

    /*
     * @Description: 账户列表
     * @Author: lu
     * @Date: 2022/4/19 9:43
     * @param jsonObject:
     * @return: com.ocom.common.resp.Result
     **/
    @PostMapping(AccessServiceUrl.URL_AccountPageOnShow)
    public Result AreaPageOnShow(@RequestBody JSONObject jsonObject) {
        if (jsonObject.getString("comId") == null || jsonObject.getInteger("page") == null || jsonObject.getInteger("size") == null) {
            return ResultUtil.error(ResultEnum.Err_203);
        }
//        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        jsonObject.put("comId",jsonObject.getLong("comId"));
        jsonObject.put("userName", jsonObject.getString("account"));
        jsonObject.put("role", jsonObject.getString("accountType"));
        Result humanResult = humanClientService.getMngUserInfo(jsonObject);
        if (humanResult.getCode() == 200) {
            JSONObject retJsonObject = JSON.parseObject(JSON.toJSONString(humanResult.getData()));
            List<EntityMngUserInfo> entityMngUserInfoList = JSON.parseArray(JSON.toJSONString(retJsonObject.get("list")), EntityMngUserInfo.class);
            List<JSONObject> list = new ArrayList<>();
            for (EntityMngUserInfo entityMngUserInfo : entityMngUserInfoList) {
                String regionId = String.valueOf(entityMngUserInfo.getRegionId());
                String areaId = String.valueOf(entityMngUserInfo.getAreaId());
                String deptId = String.valueOf(entityMngUserInfo.getDeptId());
                JSONObject reJsonObject = JSON.parseObject(JSON.toJSONString(entityMngUserInfo));
                Result sccessResult = accessClientService.GetAreaInfo(entityMngUserInfo.getComId(), Integer.valueOf(regionId), Integer.valueOf(areaId), "");
                if (sccessResult.getCode() == 200) {
                    try {
                        if (sccessResult.getData() != null) {
                            List<EntityMjAreaInfo> entityMjAreaInfos = JSON.parseArray(JSON.toJSONString(sccessResult.getData()), EntityMjAreaInfo.class);
                            for (EntityMjAreaInfo entityMjAreaInfo : entityMjAreaInfos) {
                                reJsonObject.put("areaName", entityMjAreaInfo.getAreaName());
                            }
                        }
                    } catch (Exception e) {

                    }
                }
                try {
                    RespMachMessage srvpaccessResult = srvpaccessClientService.getRegionInfo(entityMngUserInfo.getComId(), Integer.valueOf(regionId), Integer.valueOf(deptId), null);
                    if (srvpaccessResult.getCode().equals("0000")) {
                        List<EntityMjRegionInfo> entityMjRegionInfoList = JSON.parseArray(JSON.toJSONString(srvpaccessResult.getData()), EntityMjRegionInfo.class);
                        for (EntityMjRegionInfo entityMjRegionInfo : entityMjRegionInfoList) {
                            reJsonObject.put("regionName", entityMjRegionInfo.getRegionName());
                        }
                    }
                } catch (Exception e) {

                }
                Long comID = entityMngUserInfo.getComId();
                Long deptID = entityMngUserInfo.getDeptId();
                Result result = humanClientService.GetDeptInfo(comID, deptID, null);
                if (result.getCode() == 200) {
                    List<EntityDeptInfo> entityDeptInfos = JSON.parseArray(JSON.toJSONString(result.getData()), EntityDeptInfo.class);
                    if (entityDeptInfos.size() > 0) {
                        for (EntityDeptInfo entityDeptInfo : entityDeptInfos) {
                            if (entityDeptInfo != null) {
                                if (entityDeptInfo.getComId().equals(entityMngUserInfo.getComId()) &&
                                        entityDeptInfo.getDeptId().equals(entityMngUserInfo.getDeptId())) {
                                    reJsonObject.put("deptName", entityDeptInfo.getDeptName());
                                }
                            }
                        }
                    }
                }

                reJsonObject.put("account", entityMngUserInfo.getUserName());
                reJsonObject.remove("userName");
                reJsonObject.put("accountType", entityMngUserInfo.getRole());
                reJsonObject.remove("role");
                reJsonObject.remove("salt");
                reJsonObject.remove("password");
                list.add(reJsonObject);
            }
            retJsonObject.put("list", list);
            return ResultUtil.success(retJsonObject);
        } else {
            return humanResult;
        }
    }

    /*
     * @Description:新增账户
     * @Author: lu
     * @Date: 2022/4/19 15:04
     * @param jsonObject:
     * @return: com.ocom.common.resp.Result
     **/
    @PostMapping(AccessServiceUrl.URL_AccountPageAdd)
    public Result accountPageAdd(@RequestBody JSONObject jsonObject) {
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        //权限越界 添加比自己大的权限
        if (jsonObject.getInteger("accountType").compareTo(yoCiUser.getRole().intValue()) < 0) {
            return ResultUtil.error(ResultEnum.Err_3066);
        }
        List<String> errors = PasswordValidator.validatePassword(jsonObject.getString("password"));
        if (!errors.isEmpty()) {
            return ResultUtil.info(500,String.join(",",errors));
        }

        jsonObject.put("comId", yoCiUser.getComId());
        jsonObject.put("userName", jsonObject.getString("account"));
        jsonObject.put("role", jsonObject.getString("accountType"));
        jsonObject.remove("account");
        jsonObject.remove("accountType");
        Result humanResult = humanClientService.accountPageAdd(jsonObject);
        if (humanResult.getCode() == 200) {
            return ResultUtil.success();
        } else {
            return humanResult;
        }
    }

    /*
     * @Description:修改账户
     * @Author: lu
     * @Date: 2022/4/19 17:59
     * @param jsonObject:
     * @return: com.ocom.common.resp.Result
     **/
    @PostMapping(AccessServiceUrl.URL_AccountPageModify)
    public Result accountPageModify(@RequestBody JSONObject jsonObject) {

        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        if (Integer.valueOf(jsonObject.getString("accountType")).compareTo(yoCiUser.getRole().intValue()) < 0) {
            return ResultUtil.error(ResultEnum.Err_3066);
        }

        if(!CommonUtil.isNull(jsonObject.getString("password"))){

            List<String> errors = PasswordValidator.validatePassword(jsonObject.getString("password"));

            if (!errors.isEmpty()) {
                return ResultUtil.info(500,String.join(",",errors));
            }
//            return ResultUtil.error(ResultEnum.Err_3107);
        }

        jsonObject.put("comId", yoCiUser.getComId());
        jsonObject.put("userName", jsonObject.getString("account"));
        jsonObject.put("role", jsonObject.getString("accountType"));
        jsonObject.remove("account");
        jsonObject.remove("accountType");
        Result humanResult = humanClientService.accountPageModify(jsonObject);
        if (humanResult.getCode() == 200) {
            return ResultUtil.success();
        } else {
            return humanResult;
        }
    }

    /*
     * @Description:删除账户
     * @Author: lu
     * @Date: 2022/4/19 17:59
     * @param jsonObject:
     * @return: com.ocom.common.resp.Result
     **/
    @PostMapping(AccessServiceUrl.URL_AccountPageDelete)
    public Result accountPageDelete(@RequestBody JSONObject jsonObject) {
        YoCiUser yociuser = SecurityUtils.getYoCiUser();
        jsonObject.put("comId",yociuser.getComId());
        Result humanResult = humanClientService.deleteMngUserInfo(jsonObject);
        if (humanResult.getCode() == 200) {
            return ResultUtil.success();
        } else {
            return humanResult;
        }
    }

    @PostMapping(AccessServiceUrl.URL_AccountPageRole)
    public Result AccountPageRole(@RequestBody AccountPageBaseDto request) {
        List<CompanyRoleListVo> sysRoleList = new ArrayList<>();
        List<CompanyRoleListVo> roleList = new ArrayList<>();
        try {
            Result getSysRole = humanClientService.getSysRoleList();


            if (getSysRole.getCode() == 200) {
                Map sysRoleMap = JSON.parseObject(JSON.toJSONString(getSysRole.getData()), Map.class);
                sysRoleList = JSON.parseArray(JSON.toJSONString(sysRoleMap.get("roleList")), CompanyRoleListVo.class);
                sysRoleList = sysRoleList.stream().filter(o -> 21 < Integer.parseInt(o.getRole().toString())).collect(Collectors.toList());
            }
            GetCompanyRoleListDto getCompanyRoleListDto = new GetCompanyRoleListDto();
            getCompanyRoleListDto.setComId(request.getComId());
            Result getCompanyRole = companyClientService.getCompanyRole(getCompanyRoleListDto);


            if (getCompanyRole.getCode() == 200) {
                roleList = JSON.parseArray(JSON.toJSONString(getCompanyRole.getData()), CompanyRoleListVo.class);

                Set<Long> rolesToRemove = roleList.stream().filter(role -> role.getParentRole() > 21).map(CompanyRoleListVo::getParentRole).collect(Collectors.toSet());
                if (!rolesToRemove.isEmpty() && sysRoleList != null) {
                    sysRoleList.removeIf(sysRole -> rolesToRemove.contains(sysRole.getRole()));
                }
                roleList.addAll(sysRoleList);
                roleList = roleList.stream()
                        .peek(role -> {
                            role.setParentRoleName(null);
                        })
                        .collect(Collectors.toList());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.success(roleList);
    }

    @PostMapping(AccessServiceUrl.URL_AccountPageDockList)
    public Result AccountPageDockList(@RequestBody AccountPageBaseDto request) {
        Result getComDockPageList = companyClientService.getComDockPageList(request.getComId());
        List<ComDockApiListVo> list = new ArrayList<>();
        if (200 == getComDockPageList.getCode()) {
            list = JSON.parseArray(JSON.toJSONString(getComDockPageList.getData()), ComDockApiListVo.class);
            list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getDockCode()))), ArrayList :: new));
        }
        return ResultUtil.success(list);
    }

    @PostMapping(AccessServiceUrl.URL_AccountPageDockUserList)
    public Result DockUserList(@RequestBody AccountPageBaseDto request) {
        CompanyDockListDto companyDockListDto = new CompanyDockListDto();
        companyDockListDto.setComId(request.getComId());
        Result getComDockList = companyClientService.getComDockList(companyDockListDto);
        List<CompanyDockListVo> list = new ArrayList<>();
        if (200 == getComDockList.getCode()) {
            list = JSON.parseArray(JSON.toJSONString(getComDockList.getData()), CompanyDockListVo.class);
        }
        return ResultUtil.success(list);
    }

    @PostMapping(AccessServiceUrl.URL_AccountPageEditDockUser)
    public Result EditDockUser(@RequestBody RefreshUserDockDto request) {
        return humanClientService.refreshUserDock(request);
    }

    @PostMapping(AccessServiceUrl.URL_AccountPageDeleteDockUser)
    public Result DeleteDockUser(@RequestBody RefreshUserDockDto request) {
        request.setUserName(null);
        return humanClientService.refreshUserDock(request);
    }

}
